import { _decorator, Component, instantiate, Node, NodePool, sp, tween, UITransform, v2, v3, Vec3 } from 'cc';
import { Ab_EGameFloat_bA, Ab_GameFloatIns_bA, Ab_GetGameFloatComponent_bA, Ab_GetGameFloatPrefab_bA } from '../float/float.game.config';
const { ccclass, property } = _decorator;

@ccclass('Ab_GameFloat_bA')
export class Ab_GameFloat_bA extends Component {
	private static _ins: Ab_GameFloat_bA;
	/** 全局唯一安全实例 */
	public static get ins(){
		return Ab_GameFloat_bA._ins;
	}

	private Ab_xx_pool_bA: NodePool;
	private Ab_xx_demo_bA: Node;
	private Ab_uitrans_bA: UITransform;

	protected onLoad(): void {
		Ab_GameFloat_bA._ins = this;
		this.Ab_uitrans_bA = this.node.getComponent(UITransform);
		this.Ab_xx_demo_bA = this.node.getChildByName('xingxing');
		this.Ab_xx_pool_bA = new NodePool();
		this.Ab_xx_pool_bA.put(this.Ab_xx_demo_bA);
	}

	private static float_pool: Map<any, NodePool> = new Map();

	private static async Ab_getFloat_bA<F extends Ab_EGameFloat_bA>(f: F): Promise<Ab_GameFloatIns_bA<F>>{
		let pool = Ab_GameFloat_bA.float_pool.get(f);
		if(!pool){
			pool = new NodePool();
			Ab_GameFloat_bA.float_pool.set(f, pool);
		}

		let node: Node;
		if(pool.size() > 0) node = pool.get();
		else{
			node = instantiate(await Ab_GetGameFloatPrefab_bA(f));
		}

		// @ts-ignore
		return node.getComponent(await Ab_GetGameFloatComponent_bA(f));
	}

	public static Ab_recycleFlot_bA(sign: any, node: Node){
		let pool = Ab_GameFloat_bA.float_pool.get(sign);
		if(!pool){
			pool = new NodePool();
			Ab_GameFloat_bA.float_pool.set(sign, pool);
		}

		pool.put(node);
	}

	public static async Ab_Hint_bA(str: string){
		let comp = await this.Ab_getFloat_bA(Ab_EGameFloat_bA.Ab_HINT_bA);
		comp.node.setParent(Ab_GameFloat_bA.ins.node);

		Ab_GameFloat_bA.Ab_recycleFlot_bA(Ab_EGameFloat_bA.Ab_HINT_bA, await comp.show(str));
	}

	private static Ab_prop_pool_bA: Map<Node, NodePool> = new Map();
	private static Ab_prop_list_bA: Array<{type: 'stash'|'revoke'|'shuffle', icon: Node, node: Node}> = [];
	public static Ab_addProp_bA(type: 'stash' | 'revoke' | 'shuffle', icon: Node){
		let pool = this.Ab_prop_pool_bA.get(icon);
		if(!pool){
			pool = new NodePool();
			this.Ab_prop_pool_bA.set(icon, pool);
		}

		let node = pool.get() ?? instantiate(icon);
		node.setParent(Ab_GameFloat_bA.ins.node);
		node.setPosition(Ab_GameFloat_bA.ins.Ab_uitrans_bA.convertToNodeSpaceAR(icon.worldPosition));

		this.Ab_prop_list_bA.push({type, icon, node});
	}

	public static Ab_moveProp_bA(type: 'stash' | 'revoke' | 'shuffle', target_node: Node){
		let list = this.Ab_prop_list_bA.filter(el=>el.type==type);

		if(list.length <= 0) return Promise.resolve(0);

		let target_pos = Ab_GameFloat_bA.ins.Ab_uitrans_bA.convertToNodeSpaceAR(target_node.worldPosition);
		let temp_pos = v3(0, 50, 0);

		let count = list.length;
		let np = new abi.Ab_NudityPromise_bA<number>();
		list.forEach((el, i, ls)=>{
			abi.Ab_array_bA.Ab_remove_bA(Ab_GameFloat_bA.Ab_prop_list_bA, el);
			let [ui_n, ui_t] = [el.node, target_node].map(n=>n.getComponent(UITransform));

			let scale = Math.min(ui_t.width / ui_n.width, ui_t.height / ui_n.height);

			tween(el.node)
			.by(0.2, {position: temp_pos}, {easing: 'cubicOut'})
			.to(0.5, {position: target_pos, scale: v3(scale, scale, el.node.scale.z)}, {easing: 'cubicOut'})
			.call(()=>{
				count--;
				if(count <= 0) np.Ab_resolve_bA(ls.length);

				let pool = this.Ab_prop_pool_bA.get(el.icon);
				if(!pool){
					pool = new NodePool();
					this.Ab_prop_pool_bA.set(el.icon, pool);
				}
				pool.put(el.node);
				el.node.setScale(1, 1, el.node.scale.z);
			}).start();
		});

		return np.Ab_promise_bA;
	}

	private static Ab_hilight_token_bA: Map<string, {depth: number[], node: Node, parent: Node}[]> = new Map();

	public static Ab_heightLight_bA(list: Node[]){
		let canvas = abi.Ab_cc_bA.Ab_canvas_bA;
		let base = this.ins.node.children.length;

		let info = list.filter(n=>n && n.isValid).map(node=>{
			let depth: number[] = [];
			let r = node;
			while(r!=canvas.node){
				depth.unshift(r.getSiblingIndex());
				r = r.parent;
			}
			return {depth, node, parent: node.parent};
		}).sort((a, b)=>{
			let i = 0;
			while(a.depth[i]==b.depth[i]) i++;
			return a.depth[i] - b.depth[i];
		});

		info.forEach((el, i)=>{
			el.node.setParent(Ab_GameFloat_bA.ins.node, true);
			el.node.setSiblingIndex(base + i);
		});

		let token = abi.Ab_string_bA.Ab_randomToken_bA(5, 36, t=>!Ab_GameFloat_bA.Ab_hilight_token_bA.has(t));

		Ab_GameFloat_bA.Ab_hilight_token_bA.set(token, info);

		return token;
	}

	public static Ab_releaseHILIT_bA(token: string){
		if(!this.Ab_hilight_token_bA.has(token)) return void 0;

		let info = this.Ab_hilight_token_bA.get(token);
		this.Ab_hilight_token_bA.delete(token);

		info.forEach(el=>{
			el.node.setParent(el.parent, true);
			el.node.setSiblingIndex(el.depth.pop());
		});
	}

	public static Ab_XX_bA(world_position: Vec3, scale: number){
		scale = scale ?? 1;

		let sp_xx = (Ab_GameFloat_bA.ins.Ab_xx_pool_bA.get() ?? instantiate(Ab_GameFloat_bA.ins.Ab_xx_demo_bA)).getComponent(sp.Skeleton);

		sp_xx.node.setParent(Ab_GameFloat_bA.ins.node);
		sp_xx.loop = false;
		sp_xx.node.setScale(scale, scale, sp_xx.node.scale.z);
		sp_xx.node.setPosition(Ab_GameFloat_bA.ins.Ab_uitrans_bA.convertToNodeSpaceAR(world_position));

		sp_xx.setTrackCompleteListener(sp_xx.setAnimation(0, 'xingxing', false), ()=>{
			sp_xx.clearAnimations();
			sp_xx.clearTracks();
			Ab_GameFloat_bA.ins.Ab_xx_pool_bA.put(sp_xx.node);
		});
	}
}


